﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows;
using Molic.Core;
using Molic.Core.Controls.interfaces;
using Spring.Context;
using Spring.Context.Support;
using Common.Logging;

namespace Molic.ShapeLibrary
{
    public class ModelFactory : IMolicModelFactory
    {
        #region Constructors
        public ModelFactory() { }
        #endregion

        #region Properties
        private IApplicationContext _DependencyInjectionContext;
        /// <summary>
        /// The Spring framework IoC context.
        /// </summary>
        private IApplicationContext DependencyInjectionContext
        {
            get
            {
                if (_DependencyInjectionContext == null)
                {
                    _DependencyInjectionContext = ContextRegistry.GetContext();
                }
                return _DependencyInjectionContext;
            }
        }

        private IMolicIdentifier _ModelIdentifier;
        /// <summary>
        /// Model identifier.
        /// </summary>
        private IMolicIdentifier ModelIdentifier
        {
            get
            {
                if (_ModelIdentifier == null)
                {
                    // identify the current object dragged
                    _ModelIdentifier = (IMolicIdentifier)DependencyInjectionContext.GetObject("ModelIdentifier");
                }
                return _ModelIdentifier;
            }
        }

        private ILog _logger;
        /// <summary>
        /// Logger.
        /// </summary>
        private ILog Logger
        {
            get
            {
                if (_logger == null)
                {
                    _logger = LogManager.GetLogger(this.GetType());
                }
                return _logger;
            }
        }

        #endregion

        #region Private Members
        /// <summary>
        /// Sets all properties needed.
        /// </summary>
        /// <param name="ModelName">The model name.</param>
        /// <returns>The new model.</returns>
        private object ConfigureModel(string ModelName, MolicUIElement Model)
        {
            Model.ModelName = ModelName;
            return Model;
        }
        /// <summary>
        /// Sets all properties needed.
        /// </summary>
        /// <param name="ModelName"></param>
        /// <param name="id"></param>
        /// <param name="newItem"></param>
        private void ConfigureModel(string ModelName, Guid id, MolicUIElement Model)
        {
            ConfigureModel(ModelName, Model);
            Model.ID = id;
        }
        #endregion

        #region IMolicModelFactory Members
        /// <summary>
        /// Create a new model of Molic UI Element.
        /// </summary>
        /// <param name="VisualReference"></param>
        /// <returns></returns>
        public MolicUIElement CreateModel(object VisualReference)
        {
            // get the name that identify the model that have to be created
            string name = ModelIdentifier.IdentifyModel(VisualReference);

            // create the new model
            MolicUIElement newItem = null;
            try
            {
                // create a new model using its name to find a new instance
                newItem = CreateModel(name);
            }
            catch (Spring.Objects.Factory.NoSuchObjectDefinitionException ex)
            {
                string message = string.Format("Could not create an instance of a model called {0}.", name);
                Logger.Error(message);
                newItem = new MolicUIElement();
                newItem.Content = VisualReference;
            }
            return newItem;
        }
        /// <summary>
        /// Creates a new model using the model name.
        /// </summary>
        /// <param name="ModelName"></param>
        /// <returns></returns>
        public MolicUIElement CreateModel(string name)
        {
            MolicUIElement newItem = (MolicUIElement)DependencyInjectionContext.GetObject(name);
            // sets the name that identifies the model
            ConfigureModel(name, newItem);
            return newItem;
        }
        #endregion

        #region IMolicModelFactory Members

        public MolicUIElement CreateModel(string ModelName, Guid id)
        {
            MolicUIElement newItem = (MolicUIElement)DependencyInjectionContext.GetObject(ModelName);
            // sets the name that identifies the model
            ConfigureModel(ModelName, id, newItem);
            return newItem;
        }
        #endregion
    }
}
